package com.weishuang.monitor.leader.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.weishuang.monitor.leader.commons.enums.SCODE;
import com.weishuang.monitor.leader.commons.utils.IpUtils;
import com.weishuang.monitor.leader.entity.*;
import com.weishuang.monitor.leader.entity.ServerCpuRealTime;
import com.weishuang.monitor.leader.entity.ServerDiskInfo;
import com.weishuang.monitor.leader.entity.ServerRamRealTime;
import com.weishuang.monitor.leader.entity.ServersRunInfo;
import com.weishuang.monitor.leader.mapper.ServersRunInfoMapper;
import com.weishuang.monitor.leader.service.IServersRunInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * <p>
 * 服务器运行信息表 服务实现类
 * </p>
 *
 * @author weishuang
 * @since 2021-03-23
 */
@Service
public class ServersRunInfoServiceImpl extends ServiceImpl<ServersRunInfoMapper, ServersRunInfo> implements IServersRunInfoService {

    @Value("${leader.checkOnlineMsec:10000}")
    private Long checkOnlineMsec;

    @Autowired
    private EmailSendService emailSendService;

    @Override
    public void onlineServer(String sysId) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String remoteAddr = IpUtils.getRemoteAddr(request);
        ServersRunInfo serversRunInfo = new ServersRunInfo();
        serversRunInfo.setSysId(sysId);
        serversRunInfo.setNetIp(remoteAddr);
        serversRunInfo.setOnlineStatus(SCODE.YES_CODE.getValue());
        serversRunInfo.setUpdatedTime(new Date());
        this.saveOrUpdate(serversRunInfo);
    }

    @Override
    public void upCpu(ServerCpuRealTime serverCpuRealTime) {
        ServersRunInfo serversRunInfo = new ServersRunInfo();
        serversRunInfo.setSysId(serverCpuRealTime.getSysId());
        serversRunInfo.setCpuUsageRate(serverCpuRealTime.getUsegeRate());
        serversRunInfo.setOnlineStatus(SCODE.YES_CODE.getValue());
        serversRunInfo.setUpdatedTime(new Date());
        this.saveOrUpdate(serversRunInfo);
    }

    @Override
    public void upRam(ServerRamRealTime serverRamRealTime) {
        ServersRunInfo serversRunInfo = new ServersRunInfo();
        serversRunInfo.setSysId(serverRamRealTime.getSysId());
        BigDecimal usage = new BigDecimal("0");
        if (serverRamRealTime.getTotal() != null && !serverRamRealTime.getTotal().equals(0l)) {
            BigDecimal use = new BigDecimal(String.valueOf(serverRamRealTime.getTotal() - serverRamRealTime.getAvailable()));
            usage = use.divide(new BigDecimal(String.valueOf(serverRamRealTime.getTotal())),4, BigDecimal.ROUND_DOWN).multiply(new BigDecimal("100"));
        }
        serversRunInfo.setRamUsageRate(usage);
        serversRunInfo.setOnlineStatus(SCODE.YES_CODE.getValue());
        serversRunInfo.setUpdatedTime(new Date());
        this.saveOrUpdate(serversRunInfo);
    }

    @Override
    public void upDisk(String sysId, List<ServerDiskInfo> serverDiskInfos) {
        AtomicReference<Long> total = new AtomicReference<>(0l);
        AtomicReference<Long> free = new AtomicReference<>(0l);
        serverDiskInfos.forEach(serverDiskInfo -> {
            total.updateAndGet(v -> v + serverDiskInfo.getDiskSpace());
            free.updateAndGet(v -> v + serverDiskInfo.getDiskSpaceFree());
        });
        Long space = total.get();
        Long spaceFree = free.get();
        BigDecimal divide = new BigDecimal(String.valueOf(space - spaceFree)).divide(new BigDecimal(String.valueOf(space)),4,BigDecimal.ROUND_DOWN).multiply(new BigDecimal("100"));
        ServersRunInfo serversRunInfo = new ServersRunInfo();
        serversRunInfo.setSysId(sysId);
        serversRunInfo.setDiskUsageRate(divide);
        serversRunInfo.setOnlineStatus(SCODE.YES_CODE.getValue());
        serversRunInfo.setUpdatedTime(new Date());
        this.saveOrUpdate(serversRunInfo);
    }

    /**
     * 执行服务器在线检查
     */
    @Override
    public void serverOnlineCheck() {
        //查询所有子线的服务器列表
        LambdaQueryWrapper<ServersRunInfo> eq = Wrappers.lambdaQuery(ServersRunInfo.class).eq(ServersRunInfo::getOnlineStatus, SCODE.YES_CODE.getValue());
        List<ServersRunInfo> serversRunInfos = baseMapper.selectList(eq);
        Long currentDateLong = new Date().getTime();
        List<ServersRunInfo> upServer = new ArrayList<>();
        serversRunInfos.forEach(serversRunInfo -> {
            //判断数据时间最新是否距离现在是否大于10秒。是则离线。否在在线
            if (currentDateLong - serversRunInfo.getUpdatedTime().getTime() > checkOnlineMsec) {
                ServersRunInfo server = new ServersRunInfo();
                server.setSysId(serversRunInfo.getSysId());
                server.setOnlineStatus(SCODE.NO_CODE.getValue());
                upServer.add(server);
                emailSendService.sendOffLineEmail(serversRunInfo.getSysId());
            }
        });
        this.updateBatchById(upServer);
    }


}
